// 连接数据库并将数据展示在页面上

const path = require('path');

const mariadb = require('mariadb');

const express = require('express');
const eat = require('express-art-template');


const port = 8080;
const app = express();

//模板渲染
app.engine('art', eat);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', '.art');
eat.template.defaults.imports.format = require('dateformat');

// 指定数据库连接池配置
const config = {
    /* 主机地址 */
    host: 'localhost',
    /* 端口号 */
    port: 3306,
    /* 数据库名称 */
    database: 'ecut',
    /* 用户名 */
    user: 'root',
    /* 连接数限制 */
    connectionLimit: 5
}

// 使用mariadb提供的支持创建数据库连接池
const pool = mariadb.createPool(config);
// 从 数据库连接池 中获得 数据库连接
const connection = pool.getConnection();

// 处理静态资源
app.use(express.static('public'));

//取数据库中的数据显示到list页面
app.get('/', (req, resp) => {

    // 当成功获得数据库连接时执行的操作
    let fulfillment = function(conn) {

        let select = 'SELECT * FROM t_student';
        // 使用 conn 提供的支持完成查询操作
        let p = conn.query(select);
        console.log(p);

        p.then(rows => {
            // 声明数组用来保存查询结果中的每行记录
            let students = [];
            // 判断返回的结果是否是数组
            if (Array.isArray(rows)) {
                // 遍历数据库返回的结果并将其中每个元素重新添加到students数组中
                rows.forEach(e => {
                    students.push(e);
                });
            }

            // 准备模板上使用的数据
            let data = { students: students }

            // 查询成功后渲染模板
            resp.render('list', data);
        }).catch(error => {
            console.log(error);
            resp.send('<p>查询失败</p>');
        }).finally(() => {
            //用完后将 连接 归还到 连接池
            conn.release();
        });

    }

    // 当获得数据库连接时发生故障则执行该操作
    let rejection = error => {
        console.log(error);
        resp.send('<p>数据库连接失败</p>');
    }

    // 当成功获得数据库连接后就执行 then 函数第一个参数传入的函数
    // 当获得连接失败时就执行 catch 函数的参数传入的函数
    connection.then(fulfillment).catch(rejection);

});

//删除信息
app.get('/remove/:id', (req, resp) => {
    console.log('接受到的id是: ', req.params.id);

    let success = function(conn) {
        // 确定被执行的删除语句( 其中的问号是 参数占位符 )
        let remove = 'DELETE FROM t_student WHERE id = ? ';
        // 在数组中指定 各个参数占位符 的 值
        let params = [req.params.id];
        // 使用 conn 提供的支持完成删除操作
        let p = conn.query(remove, params);

        p.then(result => {
            console.log(result);
            // resp.send('<p>删除成功</p>');
            resp.redirect('/');
        }).catch(err => {
            resp.send('<p>删除失败</p>');
        }).finally(() => {
            //用完后将 连接 归还到 连接池
            conn.release();
        });
    }

    let fail = function(error) {
        console.log('连接失败: ', error);
    }
    connection.then(success).catch(fail);

});

//使用url编码的有效负载解析传入请求
app.use(express.urlencoded({ extended: true }));

//添加信息
app.post('/add', (req, resp) => {
    let success = function(conn) {
        // 确定被执行的添加语句( 其中的问号是 参数占位符 )
        let insert = 'INSERT INTO t_student VALUES(?,?,?,?,?)';
        // 在数组中指定 各个参数占位符 的 值
        let params = [req.body.id, req.body.name, req.body.gender, req.body.birthdate, req.body.hometown];
        // 使用 conn 提供的支持完成添加操作
        let p = conn.query(insert, params);

        p.then(result => {
            console.log(result);
            // resp.send('<p>添加成功</p>');
            resp.redirect('/');
        }).catch(err => {
            resp.send('<p>添加失败</p>');
        }).finally(() => {
            //用完后将 连接 归还到 连接池
            conn.release();
        });
    }

    let fail = function(error) {
        console.log('连接失败: ', error);
    }
    connection.then(success).catch(fail);

});

//更新信息
app.get('/update/:id', (req, resp) => {
    console.log(req.params.id);
    // 当成功获得数据库连接时执行的操作
    let fulfillment = function(conn) {

        let select = 'SELECT * FROM t_student WHERE ID=?';
        // 使用 conn 提供的支持完成查询操作
        let params = req.params.id;
        let p = conn.query(select, params);
        console.log(p);

        p.then(rows => {
            // 准备模板上使用的数据
            let data = { students: rows[0] }

            // 查询成功后渲染模板
            resp.render('update', data);
        }).catch(error => {
            console.log(error);
            resp.send('<p>查询失败</p>');
        }).finally(() => {
            //用完后将 连接 归还到 连接池
            conn.release();
        });
    }

    // 当获得数据库连接时发生故障则执行该操作
    let rejection = error => {
        console.log(error);
        resp.send('<p>数据库连接失败</p>');
    }
    connection.then(fulfillment).catch(rejection);
});
app.post('/update', (req, resp) => {
    let success = function(conn) {
        // 确定被执行的添加语句( 其中的问号是 参数占位符 )
        let update = 'UPDATE t_student SET ID=?,NAME=?,GENDER=?,BIRTHDATE=?,HOMETOWN=? WHERE ID=?';
        // 在数组中指定 各个参数占位符 的 值
        let params = [req.body.id, req.body.name, req.body.gender, req.body.birthdate, req.body.hometown, req.body.id];
        // 使用 conn 提供的支持完成添加操作
        let p = conn.query(update, params);
        console.log(p);
        p.then(result => {
            console.log(result);
            // resp.send('<p>添加成功</p>');
            resp.redirect('/');
        }).catch(err => {
            resp.send('<p>添加失败</p>');
        }).finally(() => {
            //用完后将 连接 归还到 连接池
            conn.release();
        });
    }

    let fail = function(error) {
        console.log('连接失败: ', error);
    }
    connection.then(success).catch(fail);
});
app.listen(port);